home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / EffectEdit / TextView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  9.6 KB  |  372 lines

  1. // TextView.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "EffectEdit.h"
  6. #include "OptionsView.h"
  7. #include "EffectDoc.h"
  8. #include "MainFrm.h"
  9. #include "TextView.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. extern CEffectEditApp theApp;
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CTextView
  21.  
  22. IMPLEMENT_DYNCREATE(CTextView, CFormView)
  23.  
  24. CTextView::CTextView()
  25.     : CFormView(CTextView::IDD)
  26. {
  27.     //{{AFX_DATA_INIT(CTextView)
  28.     m_strEdit = _T("");
  29.     //}}AFX_DATA_INIT
  30.     m_pFRDlg = NULL;
  31. }
  32.  
  33. CTextView::~CTextView()
  34. {
  35. }
  36.  
  37. void CTextView::DoDataExchange(CDataExchange* pDX)
  38. {
  39.     CFormView::DoDataExchange(pDX);
  40.     //{{AFX_DATA_MAP(CTextView)
  41.     DDX_Text(pDX, IDC_EDIT, m_strEdit);
  42.     //}}AFX_DATA_MAP
  43. }
  44.  
  45.  
  46. static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);
  47.  
  48. BEGIN_MESSAGE_MAP(CTextView, CFormView)
  49.     //{{AFX_MSG_MAP(CTextView)
  50.     ON_WM_TIMER()
  51.     ON_WM_SIZE()
  52.     ON_EN_CHANGE(IDC_EDIT, OnChangeEdit)
  53.     ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
  54.     ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
  55.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  56.     ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  57.     ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  58.     ON_COMMAND(ID_EDIT_FIND, OnEditFind)
  59.     ON_WM_KEYDOWN()
  60.     ON_REGISTERED_MESSAGE( WM_FINDREPLACE, OnFindReplace )
  61.     //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63.  
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CTextView diagnostics
  66.  
  67. #ifdef _DEBUG
  68. void CTextView::AssertValid() const
  69. {
  70.     CFormView::AssertValid();
  71. }
  72.  
  73. void CTextView::Dump(CDumpContext& dc) const
  74. {
  75.     CFormView::Dump(dc);
  76. }
  77.  
  78. CEffectDoc* CTextView::GetDocument() // non-debug version is inline
  79. {
  80.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEffectDoc)));
  81.     return (CEffectDoc*)m_pDocument;
  82. }
  83. #endif //_DEBUG
  84.  
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CTextView message handlers
  87.  
  88. void CTextView::OnSize(UINT nType, int cx, int cy) 
  89. {
  90.     SetScrollSizes( MM_TEXT, CSize(cx, cy) );
  91.  
  92.     CFormView::OnSize(nType, cx, cy);
  93.     
  94.     CWnd* pGroup = GetDlgItem(IDC_GROUPBOX);
  95.     CWnd* pEdit = GetDlgItem(IDC_EDIT);
  96.  
  97.     if( pGroup != NULL && 
  98.         pEdit != NULL )
  99.     {
  100.         CRect rc;
  101.  
  102.         pGroup->SetWindowPos(NULL, 7, 2, cx - 7 - 4, cy - 2 - 10, SWP_NOZORDER);
  103.  
  104.         pGroup->GetClientRect(&rc);
  105.         pGroup->MapWindowPoints(this, &rc);
  106.  
  107.         rc.InflateRect( -10, -17, -10, -10 );
  108.         pEdit->SetWindowPos(NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER);
  109.     }
  110. }
  111.  
  112. void CTextView::OnInitialUpdate() 
  113. {
  114.     if( m_MyEdit.GetSafeHwnd() == NULL )
  115.     {
  116.         m_MyEdit.SubclassDlgItem( IDC_EDIT, this );
  117.         m_MyEdit.SetOptions(ECOOP_OR, ECO_SAVESEL);
  118.     }
  119.  
  120.     // Set the event mask so that the parent gets notified when the text
  121.     // of the rich edit control changes. 
  122.     m_MyEdit.SetEventMask( m_MyEdit.GetEventMask() | ENM_CHANGE | ENM_SELCHANGE );
  123.  
  124.     m_strEdit = ((CEffectDoc*)GetDocument())->GetCode();
  125.     UpdateData(FALSE); // Update the edit box with the contents of m_strEdit
  126.  
  127.     UpdateFont();
  128.  
  129.     // Trigger an OnSize so scrollbars will appear
  130.     m_MyEdit.SetWindowPos( NULL, 0, 0, 0, 0, SWP_NOZORDER );
  131.     CRect rc;
  132.     GetClientRect(&rc);
  133.     OnSize( 0, rc.Width(), rc.Height() );
  134.  
  135.     m_MyEdit.RequestResize();
  136.  
  137.     CFormView::OnInitialUpdate();
  138. }
  139.  
  140. void CTextView::UpdateFont()
  141. {
  142.     DWORD dwFontSize = AfxGetApp()->GetProfileInt( TEXT("Settings"), TEXT("FontSize"), 9 );
  143.     CString strFontName = AfxGetApp()->GetProfileString( TEXT("Settings"), TEXT("FontName"), TEXT("Courier") );
  144.     CHARFORMAT cf;
  145.     cf.cbSize = sizeof(cf);
  146.     cf.dwMask = CFM_SIZE | CFM_FACE | CFM_ITALIC;
  147.     if( GetDocument()->UsingExternalEditor() )
  148.         cf.dwEffects = CFM_ITALIC;
  149.     else
  150.         cf.dwEffects = 0;
  151.     cf.yHeight = 20 * dwFontSize;
  152. #if (_RICHEDIT_VER >= 0x0200)
  153.     // Rich Edit 2.0 or later supports Unicode.
  154.     lstrcpy( cf.szFaceName, strFontName );
  155. #else
  156.     // Before 2.0, rich edit only supports ANSI.
  157.     WideCharToMultiByte( CP_ACP, 0, strFontName, -1, cf.szFaceName, sizeof(cf.szFaceName)/sizeof(cf.szFaceName[0]), NULL, NULL );
  158. #endif
  159.     m_MyEdit.SetDefaultCharFormat(cf);
  160. }
  161.  
  162. void CTextView::OnChangeEdit() 
  163. {
  164.     UpdateData();
  165.     GetDocument()->SetCode(m_strEdit);
  166.  
  167.     SetTimer( 0, 1000, NULL );
  168. }
  169.  
  170.  
  171. void CTextView::OnTimer(UINT nIDEvent)
  172. {
  173.     if( nIDEvent == 0 ) // User edited the doc and has been idle for 1000ms, so recompile
  174.     {
  175.         KillTimer( 0 );
  176.         GetDocument()->Compile();
  177.     }
  178.     else if( nIDEvent == 1 ) // Check to see if doc has changed in external editor
  179.     {
  180.         CFileStatus fileStatus;
  181.         CTime timeLastChanged;
  182.         if( GetDocument()->GetLastModifiedTime( &timeLastChanged ) )
  183.         {
  184.             if( timeLastChanged > m_timeLastChanged )
  185.             {
  186.                 GetDocument()->ReloadFromFile();
  187.                 m_strEdit = ((CEffectDoc*)GetDocument())->GetCode();
  188.                 UpdateData(FALSE);
  189.                 m_timeLastChanged = timeLastChanged;
  190.             }
  191.         }
  192.     }
  193. }
  194.  
  195. void CTextView::SelectLine(int nLine)
  196. {
  197.     int nBegin = m_MyEdit.LineIndex( nLine );
  198.     int nEnd = nBegin + m_MyEdit.LineLength( nLine );
  199.     m_MyEdit.SetSel( nBegin, nBegin/*nEnd*/ );
  200. }
  201.  
  202. void CTextView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  203. {
  204.     CView::OnUpdate( pSender, lHint, pHint );
  205.  
  206.     int iLineSelected = GetDocument()->GetSelectedLine();
  207.     if( iLineSelected != -1 )
  208.         SelectLine( iLineSelected );
  209.     
  210. }
  211.  
  212. void CTextView::OnEditUndo() 
  213. {
  214.     m_MyEdit.Undo();    
  215. }
  216.  
  217. void CTextView::OnUpdateEditUndo(CCmdUI* pCmdUI) 
  218. {
  219.     pCmdUI->Enable( m_MyEdit.CanUndo() );
  220. }
  221.  
  222. void CTextView::OnEditCopy() 
  223. {
  224.     m_MyEdit.Copy();    
  225. }
  226.  
  227. void CTextView::OnEditCut() 
  228. {
  229.     m_MyEdit.Cut(); 
  230. }
  231.  
  232. void CTextView::OnEditPaste() 
  233. {
  234.     m_MyEdit.Paste();   
  235. }
  236.  
  237. void CTextView::OnEditFind() 
  238. {
  239.     if( m_pFRDlg == NULL )
  240.     {
  241.         m_pFRDlg = new CFindReplaceDialog();
  242.     }
  243.     if( m_pFRDlg->m_hWnd == NULL )
  244.         m_pFRDlg->Create(TRUE, TEXT(""), NULL, FR_DOWN, this);
  245.     else
  246.         m_pFRDlg->BringWindowToTop();
  247. }
  248.  
  249. LRESULT CTextView::OnFindReplace(WPARAM wParam, LPARAM lParam)
  250. {
  251.     FINDREPLACE* pfr = (FINDREPLACE*)lParam;
  252.  
  253.     if( pfr->Flags & FR_DIALOGTERM )
  254.     {
  255.         m_pFRDlg = NULL;
  256.         return 0;
  257.     }
  258.  
  259.     DWORD dwFindFlags = 0;
  260.     if( pfr->Flags & FR_MATCHCASE )
  261.         dwFindFlags |= FR_MATCHCASE;
  262.     if( pfr->Flags & FR_WHOLEWORD )
  263.         dwFindFlags |= FR_WHOLEWORD;
  264.     if( pfr->Flags & FR_DOWN )
  265.         dwFindFlags |= FR_DOWN;
  266.     FINDTEXTEX FindTextEx;
  267.     m_MyEdit.GetSel(FindTextEx.chrg);
  268.     if( FindTextEx.chrg.cpMax != FindTextEx.chrg.cpMin )
  269.         FindTextEx.chrg.cpMin++;
  270.     FindTextEx.chrg.cpMax = m_MyEdit.GetTextLength() - 1;
  271. #if (_RICHEDIT_VER >= 0x0200)
  272.     // Rich Edit 2.0 or later supports Unicode.
  273.     FindTextEx.lpstrText = pfr->lpstrFindWhat;
  274. #else
  275.     // Before 2.0, rich edit only supports ANSI.
  276.     char strFindWhat[512];
  277.     WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, -1, strFindWhat, 512, NULL, NULL );
  278.     strFindWhat[511] = '\0';
  279.     FindTextEx.lpstrText = strFindWhat;
  280. #endif
  281.     if( m_MyEdit.FindText(dwFindFlags, &FindTextEx) != -1 )
  282.     {
  283.         m_MyEdit.SetSel(FindTextEx.chrgText);
  284.     }
  285.     return 0;
  286. }
  287.  
  288. void CTextView::SetExternalEditorMode(BOOL bExternal)
  289. {
  290.     UpdateFont();
  291.     m_MyEdit.SetReadOnly( bExternal );
  292.     if( bExternal )
  293.     {
  294.         GetDocument()->GetLastModifiedTime( &m_timeLastChanged );
  295.         SetTimer( 1, 1000, NULL );
  296.     }
  297.     else
  298.     {
  299.         KillTimer( 1 );
  300.     }
  301. }
  302.  
  303.  
  304. /////////////////////////////////////////////////////////////////////////////
  305. // CMyRichEditCtrl
  306.  
  307.  
  308.  
  309. BEGIN_MESSAGE_MAP(CMyRichEditCtrl, CRichEditCtrl)
  310.     //{{AFX_MSG_MAP(CMyRichEditCtrl)
  311.     ON_WM_CHAR()
  312.     //}}AFX_MSG_MAP
  313. END_MESSAGE_MAP()
  314.  
  315. CMyRichEditCtrl::CMyRichEditCtrl()
  316. {
  317.     WCHAR wszPath[MAX_PATH+1];
  318.     if( !::GetSystemDirectory( wszPath, MAX_PATH+1 ) )
  319.         return;
  320.     lstrcatW( wszPath, L"\\RICHED20.DLL" );
  321.     m_hRELibrary = LoadLibraryW( wszPath );
  322. }
  323.  
  324. CMyRichEditCtrl::~CMyRichEditCtrl()
  325. {
  326.     if( m_hRELibrary )
  327.         FreeLibrary( m_hRELibrary );
  328. }
  329.  
  330. void CMyRichEditCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  331. {
  332.     // Convert tabs to spaces
  333.     if( nChar == 9 )
  334.     {
  335.         BOOL bKeepTabs = AfxGetApp()->GetProfileInt( TEXT("Settings"), TEXT("Keep Tabs"), FALSE );
  336.         int numSpaces = AfxGetApp()->GetProfileInt( TEXT("Settings"), TEXT("Num Spaces"), 4 );
  337.  
  338.         if( bKeepTabs )
  339.         {
  340.             SendMessage(EM_REPLACESEL, TRUE, (LPARAM)"\t");
  341.         }
  342.         else
  343.         {
  344.             for( int iSpace = 0; iSpace < numSpaces; iSpace++ )
  345.                 SendMessage(EM_REPLACESEL, TRUE, (LPARAM)" ");
  346.         }
  347.     }
  348.     else
  349.     {
  350.         CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags);
  351.     }
  352. }
  353.  
  354. BOOL CTextView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  355. {
  356.     NMHDR *pHdr = (NMHDR *)lParam;
  357.  
  358.     if( pHdr->idFrom == IDC_EDIT && pHdr->code == EN_SELCHANGE )
  359.     {
  360.         // edit control's caret has moved. Find the new line and column numbers.
  361.         SELCHANGE *pSelCh = (SELCHANGE *)lParam;
  362.  
  363.         // Note: We want the first line/column to be 1, not 0.
  364.         int iRow = 1 + m_MyEdit.LineFromChar( pSelCh->chrg.cpMin );
  365.         int iCol = 1 + pSelCh->chrg.cpMin - m_MyEdit.LineIndex( -1 );
  366.  
  367.         ((CMainFrame*)theApp.GetMainWnd())->SetRowCol( iRow, iCol );
  368.     }
  369.  
  370.     return CFormView::OnNotify(wParam, lParam, pResult);
  371. }
  372.